﻿namespace LiveLabs.Logging.Logs
{
    using System;
    using System.IO;
    using Xunit;

    public class FileLogFixture : FixtureUsingFiles
    {
        [Fact]
        public void Should_Create_File_When_Not_Appending_To_Non_Existent_File()
        {
            const string fileName = "file_log.log";

            Action test = () =>
            {
                Assert.False(File.Exists(fileName));

                using (new FileLog(fileName, true))
                {
                    // do nothing
                }

                Assert.True(File.Exists(fileName));
            };

            CleanupFileIfExistsAfterTest(test, fileName);
        }

        [Fact]
        public void Should_Truncate_File_When_Not_Appending_To_Existent_File()
        {
            const string fileName = "file_log.log";

            Action test = () =>
            {
                File.WriteAllLines(fileName, new[] { "Hello World", "This will be truncated" });
                Assert.True(File.Exists(fileName));

                using (FileLog log = new FileLog(fileName, false))
                {
                    log.WriteLine("New World Order", LogLevel.Inform);
                }

                string[] lines = File.ReadAllLines(fileName);
                Assert.Equal(1, lines.Length);
                Assert.Contains("New World Order", lines);
            };

            CleanupFileIfExistsAfterTest(test, fileName);
        }

        [Fact]
        public void Should_Append_File_When_Appending_To_Existent_File()
        {
            const string fileName = "file_log.log";

            Action test = () =>
            {
                File.WriteAllLines(fileName, new[] { "Hello World", "This will not be truncated" });
                Assert.True(File.Exists(fileName));

                using (FileLog log = new FileLog(fileName, true))
                {
                    log.WriteLine("New World Order", LogLevel.Inform);
                }

                string[] lines = File.ReadAllLines(fileName);
                Assert.Equal(3, lines.Length);
                Assert.Contains("Hello World", lines);
                Assert.Contains("This will not be truncated", lines);
                Assert.Contains("New World Order", lines);
            };

            CleanupFileIfExistsAfterTest(test, fileName);
        }

        [Fact]
        public void Should_Not_Modify_File_After_Disposal()
        {
            const string fileName = "file_log.log";

            Action test = () =>
            {
                File.WriteAllLines(fileName, new[] { "Hello World", "This will not be truncated" });
                Assert.True(File.Exists(fileName));

                FileLog log = new FileLog(fileName, true);
                using (log)
                {
                    log.WriteLine("New World Order", LogLevel.Inform);
                }

                Assert.Throws<ObjectDisposedException>(() => log.WriteLine("better not show up", LogLevel.Inform));

                string[] lines = File.ReadAllLines(fileName);
                Assert.Equal(3, lines.Length);
                Assert.Contains("Hello World", lines);
                Assert.Contains("This will not be truncated", lines);
                Assert.Contains("New World Order", lines);
                Assert.DoesNotContain("better not show up", lines);
            };

            CleanupFileIfExistsAfterTest(test, fileName);
        }
    }
}
